// 参数解析模块的单元测试

use crate::args::{ArgParser, ParseError};
use crate::config::{ExecutionMode, OperationMode, OutputFormat};
use std::time::Duration;

#[test]
fn test_basic_arg_parsing() {
    let args = vec![
        "moyan".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Run);
    assert_eq!(cli_args.input_file, Some("test.墨言".to_string()));
}

#[test]
fn test_repl_mode() {
    let args = vec!["moyan".to_string(), "repl".to_string()];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Repl);
    assert_eq!(cli_args.input_file, None);
}

#[test]
fn test_debug_flag() {
    let args = vec![
        "moyan".to_string(),
        "--debug".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config.execution_mode, ExecutionMode::Debug);
    assert!(cli_args.config.show_statistics);
}

#[test]
fn test_output_format_json() {
    let args = vec![
        "moyan".to_string(),
        "--format".to_string(),
        "json".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config.output_format, OutputFormat::Json);
}

#[test]
fn test_output_format_colored() {
    let args = vec![
        "moyan".to_string(),
        "--colored".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config.output_format, OutputFormat::Colored);
}

#[test]
fn test_quiet_mode() {
    let args = vec![
        "moyan".to_string(),
        "--quiet".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config.execution_mode, ExecutionMode::Quiet);
}

#[test]
fn test_verbose_mode() {
    let args = vec![
        "moyan".to_string(),
        "--verbose".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config.execution_mode, ExecutionMode::Verbose);
    assert!(cli_args.config.show_statistics);
}

#[test]
fn test_config_file() {
    let args = vec![
        "moyan".to_string(),
        "--config".to_string(),
        "config.toml".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.config_file, Some("config.toml".to_string()));
}

#[test]
fn test_no_optimizations() {
    let args = vec![
        "moyan".to_string(),
        "--no-optimize".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert!(!cli_args.config.enable_optimizations);
}

#[test]
fn test_no_safety_checks() {
    let args = vec![
        "moyan".to_string(),
        "--no-safety".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert!(!cli_args.config.enable_safety_checks);
}

#[test]
fn test_stats_flag() {
    let args = vec![
        "moyan".to_string(),
        "--stats".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert!(cli_args.config.show_statistics);
}

#[test]
fn test_no_cache() {
    let args = vec![
        "moyan".to_string(),
        "--no-cache".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert!(!cli_args.config.enable_module_cache);
}

#[test]
fn test_timeout() {
    let args = vec![
        "moyan".to_string(),
        "--timeout".to_string(),
        "10".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(
        cli_args.config.resource_limits.max_execution_time,
        Some(Duration::from_secs(10))
    );
}

#[test]
fn test_help_mode() {
    let args = vec!["moyan".to_string(), "help".to_string()];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Help);
}

#[test]
fn test_version_mode() {
    let args = vec!["moyan".to_string(), "version".to_string()];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Version);
}

#[test]
fn test_flag_order_flexibility() {
    // 标志参数在模式之前
    let args1 = vec![
        "moyan".to_string(),
        "--debug".to_string(),
        "--format".to_string(),
        "json".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser1 = ArgParser::new(args1);
    let result1 = parser1.parse();

    // 标志参数在模式之后
    let args2 = vec![
        "moyan".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
        "--debug".to_string(),
        "--format".to_string(),
        "json".to_string(),
    ];
    let mut parser2 = ArgParser::new(args2);
    let result2 = parser2.parse();

    assert!(result1.is_ok());
    assert!(result2.is_ok());

    let cli_args1 = result1.unwrap();
    let cli_args2 = result2.unwrap();

    assert_eq!(
        cli_args1.config.execution_mode,
        cli_args2.config.execution_mode
    );
    assert_eq!(
        cli_args1.config.output_format,
        cli_args2.config.output_format
    );
}

#[test]
fn test_invalid_output_format() {
    let args = vec![
        "moyan".to_string(),
        "--format".to_string(),
        "invalid".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_err());
    match result.unwrap_err() {
        ParseError::InvalidValue {
            flag,
            value,
            expected,
        } => {
            assert_eq!(flag, "--format");
            assert_eq!(value, "invalid");
            assert_eq!(expected, "plain, json, or colored");
        }
        _ => panic!("Expected InvalidValue error"),
    }
}

#[test]
fn test_missing_config_value() {
    let args = vec!["moyan".to_string(), "--config".to_string()]; // 移除后续参数，确保会报错
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_err());
    match result.unwrap_err() {
        ParseError::MissingValue { flag } => {
            assert_eq!(flag, "--config");
        }
        _ => panic!("Expected MissingValue error"),
    }
}

#[test]
fn test_invalid_timeout() {
    let args = vec![
        "moyan".to_string(),
        "--timeout".to_string(),
        "invalid".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_err());
    match result.unwrap_err() {
        ParseError::InvalidDuration { flag, value } => {
            assert_eq!(flag, "--timeout");
            assert_eq!(value, "invalid");
        }
        _ => panic!("Expected InvalidDuration error"),
    }
}

#[test]
fn test_unknown_flag() {
    let args = vec![
        "moyan".to_string(),
        "--unknown-flag".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_err());
    match result.unwrap_err() {
        ParseError::UnknownFlag(flag) => {
            assert_eq!(flag, "--unknown-flag");
        }
        _ => panic!("Expected UnknownFlag error"),
    }
}

#[test]
fn test_default_values() {
    let args = vec![
        "moyan".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();

    // 检查默认值
    assert_eq!(cli_args.config.execution_mode, ExecutionMode::Normal);
    assert_eq!(cli_args.config.output_format, OutputFormat::Plain);
    assert!(cli_args.config.enable_optimizations);
    assert!(cli_args.config.enable_safety_checks);
    assert!(cli_args.config.enable_module_cache);
    assert_eq!(cli_args.config.encoding, "UTF-8");
    assert_eq!(cli_args.config.module_paths, vec!["examples".to_string()]);

    // 资源限制默认值
    assert_eq!(
        cli_args.config.resource_limits.max_execution_time,
        Some(Duration::from_secs(30))
    );
    assert_eq!(
        cli_args.config.resource_limits.max_memory_usage,
        Some(100 * 1024 * 1024)
    );
    assert_eq!(
        cli_args.config.resource_limits.max_loop_iterations,
        Some(1_000_000)
    );
    assert_eq!(
        cli_args.config.resource_limits.max_recursion_depth,
        Some(1000)
    );
    assert_eq!(
        cli_args.config.resource_limits.max_array_length,
        Some(10_000)
    );
}

#[test]
fn test_empty_args() {
    let args = vec!["moyan".to_string()];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Help); // 默认显示帮助
}

#[test]
fn test_no_std_flag() {
    // --no-std 标志不存在，跳过此测试或改为测试已知标志
    let args = vec![
        "moyan".to_string(),
        "--no-cache".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert!(!cli_args.config.enable_module_cache);
}

#[test]
fn test_check_mode() {
    let args = vec![
        "moyan".to_string(),
        "check".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Check);
    assert_eq!(cli_args.input_file, Some("test.墨言".to_string()));
}

#[test]
fn test_format_mode() {
    let args = vec![
        "moyan".to_string(),
        "format".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();
    assert_eq!(cli_args.mode, OperationMode::Format);
    assert_eq!(cli_args.input_file, Some("test.墨言".to_string()));
}

#[test]
fn test_multiple_flags() {
    let args = vec![
        "moyan".to_string(),
        "--debug".to_string(),
        "--format".to_string(),
        "json".to_string(),
        "--stats".to_string(),
        "--timeout".to_string(),
        "15".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser = ArgParser::new(args);
    let result = parser.parse();

    assert!(result.is_ok());
    let cli_args = result.unwrap();

    assert_eq!(cli_args.config.execution_mode, ExecutionMode::Debug);
    assert_eq!(cli_args.config.output_format, OutputFormat::Json);
    assert!(cli_args.config.show_statistics);
    assert_eq!(
        cli_args.config.resource_limits.max_execution_time,
        Some(Duration::from_secs(15))
    );
}

#[test]
fn test_case_insensitive_format() {
    let args1 = vec![
        "moyan".to_string(),
        "--format".to_string(),
        "JSON".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser1 = ArgParser::new(args1);
    let result1 = parser1.parse();

    let args2 = vec![
        "moyan".to_string(),
        "--format".to_string(),
        "json".to_string(),
        "run".to_string(),
        "test.墨言".to_string(),
    ];
    let mut parser2 = ArgParser::new(args2);
    let result2 = parser2.parse();

    assert!(result1.is_ok());
    assert!(result2.is_ok());

    let cli_args1 = result1.unwrap();
    let cli_args2 = result2.unwrap();

    assert_eq!(
        cli_args1.config.output_format,
        cli_args2.config.output_format
    );
}
